﻿using System;
using System.Security;
using System.Security.Permissions;
using System.Windows;

namespace Helper
{
    [Serializable()]
    sealed public class ObjectPermission : CodeAccessPermission, IPermission,
      IUnrestrictedPermission, ISecurityEncodable, ICloneable
    {
        private UserRoles currPerm = UserRoles.None;
        private string securableObjectName = "";
        public ObjectPermission(UserRoles currentPermissionAccess)
        {
            currPerm = currentPermissionAccess;
        }

        public ObjectPermission(PermissionState state)
        {
            throw new ArgumentException("Invalid permission state.");
        }
        public UserRoles CurrentRole
        {
            get { return currPerm; }
            set { currPerm = value; }
        }
        
        public override string ToString() { return ToXml().ToString(); }

        private ObjectPermission Clone(UserRoles currState)
        {
            ObjectPermission objPerm = (ObjectPermission)Clone();
            objPerm.CurrentRole = CurrentRole;
            return objPerm;
        }
        #region IPermission Members
        public new void Demand()
        {
            if (((IApp)Application.Current).CurrentUserRole < currPerm)
                throw new SecurityException();
        }
        public override IPermission Copy()
        {
            return (IPermission)Clone();
        }
        public bool IsUnrestricted()
        {
            return false;
        }

        private ObjectPermission VerifyTypeMatch(IPermission target)
        {
            if (GetType() != target.GetType())
                throw new ArgumentException(String.Format("target must be of the {0} type",
                    GetType().FullName));
            return (ObjectPermission)target;
        }

        public override bool IsSubsetOf(IPermission target)
        {

            if (target == null)
            {
                return false;
            }
            try
            {
                ObjectPermission operand = VerifyTypeMatch(target);
                return currPerm <= operand.CurrentRole;
            }
            catch (InvalidCastException)
            {
                throw new ArgumentException(String.Format("Argument_WrongType", this.GetType().FullName));
            }
        }
        public override IPermission Intersect(IPermission target)
        {
            if (target == null)
            {
                return null;
            }

            ObjectPermission operand = VerifyTypeMatch(target);

            UserRoles val = (UserRoles)
              Math.Min((Int32)CurrentRole, (Int32)operand.CurrentRole);
            if (val == 0) return null;

            return Clone(val);
        }
        public override IPermission Union(IPermission target)
        {
            if (target == null)
            {
                return Copy();
            }


            ObjectPermission operand = VerifyTypeMatch(target);

            return Clone((UserRoles)
              Math.Max((Int32)CurrentRole, (Int32)operand.CurrentRole));

        }
        #endregion
        #region ISecurityEncodable Members
        public override void FromXml(SecurityElement e)
        {
            String elName = e.Attribute("Name");
            securableObjectName = elName == null ? null : elName;

            return;
        }
        public override SecurityElement ToXml()
        {
            SecurityElement esd = new SecurityElement("IPermission");
            String name = typeof(ObjectPermission).AssemblyQualifiedName;
            esd.AddAttribute("Class", name);
            if (securableObjectName != null) esd.AddAttribute("Name", securableObjectName);
            return esd;
        }
        #endregion
        #region ICloneable Members


        public Object Clone() { return MemberwiseClone(); }

        #endregion
    }
}